package OrderedCoverPackage;

import EstimatorPackage.Expressions.SimpleExpression;
import HierarchyPackage.HClass;
import java.util.List;

/**
 * Partition in an ordered cover.
 * Note that this partition represents both the partition made up of the mainclass only
 * and also the partition that is all the children subtracted from the mainclass.
 *
 * @author Martin Haulrich
 */
public class OCPartition  {

    /**
     * Unique ID of this partition.
     */
    final int ID;

    /**
     * The main class of this partition.
     * If this partition has no subpartitions (children) this will be the partition itself.
     */
    public final HClass mainClass;

    /**
     * The expression corresponding to the mainClass.
     */
    final SimpleExpression mainExp;

    /**
     * The superpartition of this partition.
     * Note that this partition represents both the partition made up of the mainclass only
     * and also the partition that is all the children subtracted from the mainclass. The parent
     * is the superpartition of the mainclass-only partition.
     */
    protected OCPartition parent;

    /**
     * The subpartitions of this partition.
     */
    List<OCPartition> children;

    /**
     * Flag to tell if this partition has been ghosted. I.e. if it is actually a part of the cover.
     */
    boolean ghost;

    /**
     * The value of the logaritmic empirical probalility of this partition.
     * Note that this partition is (mainclass - children) and not (mainclass)
     */
    public double restLogEmpProb;



    /**
     * The value of the logaritmic denominator in the prior-probability of this partition.
     * Note that this partition is (mainclass - children) and not (mainclass)
     */
    public double restLogPriorProbDenom;



    /**
     * This is the weight not of the rest-partition, but of the whole partition
     * I.e. the weight of (mainclass)
     */
    protected double totalWeight;

    /**
     * Is the above fields valid
     */
    protected boolean totalWeigthSet;


     public double resLogPseuEmpProb;


    /**
     * Create new partition.
     * @param mainClass Mainclass of partition.
     * @param ID The ID this partition will have. This should be unique.
     */
    OCPartition(HClass mainClass, int ID) {

        this.mainClass = mainClass;
        this.ID = ID;
        ghost = false;
        mainExp = new SimpleExpression(mainClass);
        totalWeigthSet = false;
    }

    @Override
    public boolean equals(Object o) {

        if (o instanceof OCPartition) {
            return ID == ((OCPartition) o).ID;
        }
        return false;
    }

    @Override
    public int hashCode() {
        return ID;
    }

    /**
     * Return the weight of the partition including its subpartitions. I.e. the mainclass-partition.
     * @return The weigth of the 'whole' partition.
     */
    public double getTotalWeight() {
        if (!totalWeigthSet) {
            return Double.NaN;
        }
        return totalWeight;
    }

    /**
     * Set the weight of the partition including its subpartitions. I.e. the mainclass-partition.
     * @param totalWeight The weigth of the 'whole' partition.
     */
    public void setTotalWeight(double totalWeight) {
        if (totalWeigthSet) {
            throw new RuntimeException("This should never bee changed - it is basically final");
        }
        this.totalWeight = totalWeight;
        totalWeigthSet = true;
    }
}
